#import "GameController.h"


@implementation GameController

- (IBAction)newGame:(id)sender
{
    [self resetGame];
}

- (void)windowWillClose:(NSNotification *)aNotification
{
    [NSApp terminate:self];
}

- (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)proposedFrameSize
{
    [plugin reset];
    proposedFrameSize.width = proposedFrameSize.height + 92;
    return proposedFrameSize;
}

- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
//    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    
    // this ensures that window position is stored in the defaults
    [gameWindow setFrameAutosaveName:@"gameWindow"];

    // fix the aspect ratio based on current window size 176
//    [gameWindow setAspectRatio:NSMakeSize([gameWindow frame].size.width,
//                                          [gameWindow frame].size.height)];

    // show the window
    history = [History sharedInstance];
    plugin = [PluginController sharedInstance];
    [self resetGame];
    [gameWindow makeKeyAndOrderFront:nil];
//    [blackIcon setImage:[plugin imageNamed:@"black"]];
//    [whiteIcon setImage:[plugin imageNamed:@"white"]];
    [self prefsChanged];
}


- (void)awakeFromNib
{
/*    NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
    
    [dict setObject:@"MacIago Appearance" forKey:@"PluginType"];
    [dict setObject:@"1.0" forKey:@"PluginVersion"];
    [dict setObject:@"Miguel Marcos" forKey:@"AuthorName"];
    [dict setObject:@"http://www.rodesia.org/maciago" forKey:@"AuthorUrl"];
    
    [dict writeToFile:@"plugin-info.plist" atomically:NO];*/
}


- (void)resetGame
{
    struct board_data *data;
    BoardData *bd = [BoardData alloc];
	[bd initWithSize: [prefs boardSize]];
	oldBoardSize = [prefs boardSize];
    
    [history clearAll];
    [history addItem: bd];
    data = [bd board_data];
    context = kBlackPiece;
    computerMove = NO;
    initBoard (data, context);
    [bd set_board_data: data];
    board_data_dispose (data);
    [board setNeedsDisplay:YES];
    [self updateInfo];
}

- (void)boardHasChangedPosX:(int)x posY:(int)y
{
    int n;
    BoardData *bd;
    struct board_data *data;
    
    if (context == -1 || [board isAnimating])
    {
	[self playSound:@"Frog"];
	return;
    }
    
    bd = [[history currentItem] copy];
    data = [bd board_data];
        
    n = evaluateMove (data, x, y, context);
    
    if (n)
    {
        [bd set_board_data: data];
        [history addItem:bd];
	[self switchContext];    
	if (!moveIsPossible (data, context))
	{
//	    NSLog (@"move is not possible");
	    [self switchContext];
	    if (!moveIsPossible (data, context))
		context = -1;
	    computerMove = NO;
	}
	else
	    computerMove = [prefs modeComputer];
	
	[self playSound:@"Pop"];
	[board animate];
        [bd set_board_data: data];    
	[self updateInfo];
    }
    else
    {
//    [bd set_board_data: data];    
	[bd release];
	[self playSound:@"Frog"];
    }

    board_data_dispose (data);
}

- (void)boardFinishedAnimation
{
    if (context == -1)
    {
	[self playSound:@"Ping"];
    }
    else if (computerMove)
	[self computerMove];
}

- (void)computerMove
{
    BoardData *bd;
    struct board_data *data;
    
    bd = [[history currentItem] copy];
    [history addItem:bd];
    
    if (![AI makeComputerMove:bd turn:context level:[prefs dificulty]+1])
	return;

    data = [bd board_data];
    
    computerMove = NO;
    [self switchContext];    
    if (!moveIsPossible (data, context))
    {
//	NSLog (@"computer move is not possible");
	[self switchContext];
	if (!moveIsPossible (data, context))
	    context = -1;
	else
	    computerMove = YES;
    }
    
    [bd set_board_data: data];
    [self playSound:@"Pop"];
    [board animate];
    [self updateInfo];
    board_data_dispose (data);
}

- (void)switchContext
{
    if (context == kBlackPiece)
	context = kWhitePiece;
    else if (context == kWhitePiece)
	context = kBlackPiece;
}

- (void)updateInfo
{
    [whiteCount setIntValue:[[history currentItem] numberOfWhites]];
    [blackCount setIntValue:[[history currentItem] numberOfBlacks]];
    
    if (context == kBlackPiece)
	//[statusText setStringValue:@"Black's turn"];
	[statusText setStringValue:[self getString:@"BlackTurn"]];
    else if (context == kWhitePiece)
	[statusText setStringValue:[self getString:@"WhiteTurn"]];
    else
    {
	if ([whiteCount intValue] > [blackCount intValue])
	    [statusText setStringValue:
		       [self getString:@"GameOverWhite"]];
	else if ([whiteCount intValue] < [blackCount intValue])
	    [statusText setStringValue:
		       [self getString:@"GameOverBlack"]];
	else
	    [statusText setStringValue:
		       [self getString:@"GameOverTie"]];	
    }
}

- (NSString *)getString:(NSString *)key
{
    return [[NSBundle mainBundle]
	localizedStringForKey:key value:nil table:nil];
}

- (void)dealloc
{
    [history clearAll];
    [super dealloc];
}

- (BOOL)ghostsEnabled
{
    return [prefs showMoves];
}

- (void)playSound:(NSString *)sound
{
    if ([prefs soundEnabled])
	[[NSSound soundNamed:sound] play];
}

- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
{
    return ![prefs sheetIsActive];
}

- (void)prefsChanged
{
    if (oldBoardSize != [prefs boardSize])
	{
		[self resetGame];
	}
	
	[blackIcon setImage:[plugin imageNamed:@"black"]];
    [whiteIcon setImage:[plugin imageNamed:@"white"]];
    
    if ([plugin objectNamed:@"PluginType"] != nil)
    {
        [pluginInfo setObjectValue:[NSString stringWithFormat: @"%@ - %@ (%@)",
                                    [plugin currentPlugin],
                                    [plugin objectNamed:@"AuthorName"],
                                    [plugin objectNamed:@"AuthorUrl"]]];
    }
    else
    {
        [pluginInfo setObjectValue:@""];
    }

    [board frameChanged: nil];
    [board setNeedsDisplay:YES];
    
    if ([prefs modeComputer])
		[player2Label setStringValue:[self getString:@"ComputerLabel"]];
    else
		[player2Label setStringValue:[self getString:@"Player2Label"]];
    
    if ((context == kWhitePiece) && [prefs modeComputer])
		[self computerMove];

}

- (int)boardSize
{
    return [prefs boardSize];
}

@end
